package middleware

import (
	"basic-go/syntax/webook/internal/web"
	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v5"
	"log"
	"net/http"
	"strings"
	"time"
)

var IgnorePath = []string{"/users/signup", "/users/login", "/users/login_sms/code/send", "/users/login_sms"}

type LoginJWTMiddlewareBuilder struct {
}

func NewLoginJWTMiddlewareBuilder() *LoginJWTMiddlewareBuilder {
	return &LoginJWTMiddlewareBuilder{}
}

func (l *LoginJWTMiddlewareBuilder) CheckLoginJWT() gin.HandlerFunc {

	// 在这个方法里判断用户是否登录了
	return func(ctx *gin.Context) {

		println("请求经过了checkloginjwt")
		path := ctx.Request.URL.Path
		for _, ignorepath := range IgnorePath {
			if path == ignorepath {
				return
			}
		}

		//根据约定 token放在 Authorization 头部
		//authCode := ctx.GetHeader("Authorization")
		authCode := ctx.GetHeader("Authorization")
		if authCode == "" {
			println("经过了这里-1")
			ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}

		segs := strings.SplitN(authCode, " ", 2)
		if len(segs) != 2 {
			println("经过了这里0")
			ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}

		tokenStr := segs[1]
		var uc web.UserClaims
		token, err := jwt.ParseWithClaims(tokenStr, &uc, func(token *jwt.Token) (interface{}, error) {
			return web.JWTKey, nil
		})
		if err != nil {
			println("经过了这里1")
			ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}
		if token == nil || !token.Valid {
			println("经过了这里2")
			ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}
		if uc.UserAgent != ctx.GetHeader("User-Agent") {
			println("经过了这里3")
			ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}
		expireTime := uc.ExpiresAt
		if expireTime.Sub(time.Now()) < time.Second*30 {
			uc.ExpiresAt = jwt.NewNumericDate(time.Now().Add(time.Minute * 5))
			tokenStr, err = token.SignedString(web.JWTKey)
			ctx.Set("x-jwt-token", tokenStr)
			if err != nil {
				log.Panicln(err)
			}
		}
		ctx.Set("user", uc)
	}
}
